11.1 Set
说明:类似于数组,但是成员的值都是唯一的,没有重复的值
11.1.1 基本用法
说明:向Set加入值的时候,Set内部判断两个值是否不同,使用的算法叫做Same-value equality,它类似于===,主要的区别是NaN等于自身,而===认为NaN不等于自身
要点
- 通过
Set构造器创建实例(可以传入数组来初始化) - 使用
add实例方法添加成员
技巧:一种去除数组重复成员的方法[...new Set(array)]
Demo1: 通过 add 为 set 实例添加成员
1 | var s = new Set(); |
Demo2: 接受一个数组(或类似数组的对象)作为参数,用来初始化
1 | // 例一 |
11.1.2 Set 实例的属性和方法
11.1.2.1 实例属性
| 实例属性 | 类型 | 说明 |
|---|---|---|
Set.prototype.constructor |
function |
构造函数,默认就是Set函数 |
Set.prototype.size |
number |
Set实例的成员总数 |
11.1.2.2 操作方法
| 操作方法 | 说明 |
|---|---|
add(value) |
添加某个值,返回Set结构本身 |
delete(value) |
删除某个值,返回一个布尔值,表示删除是否成功 |
has(value) |
返回一个布尔值,表示该值是否为Set的成员 |
clear() |
清除所有成员,没有返回值 |
Demo1: 操作方法的基本使用
1 | s.add(1).add(2).add(2); |
Demo2: Array.from方法可以将Set结构转为数组
1 | var items = new Set([1, 2, 3, 4, 5]); |
Demo3: 去除数组重复成员(也可以通过扩展运算符(...)
1 | function dedupe(array) { |
11.1.2.3 遍历方法
顺序:Set的遍历顺序就是插入顺序
注意:由于Set结构的键名的键名和键值是同一个值,所以keys方法和values方法的行为完全一致
技巧:Set结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法,因此,可以省略values方法,直接用for...of循环遍历Set
| 遍历相关实例方法 | 说明 |
|---|---|
keys() |
返回键名的遍历器 |
values() |
返回键值的遍历器 |
entries() |
返回键值对的遍历器 |
forEach() |
使用回调函数遍历每个成员,和数组的forEach用法一样 |
Demo1: keys(),values(),entries()
1 | let set = new Set(['red', 'green', 'blue']); |
Demo2: 省略values方法,直接用for...of循环遍历Set
1 | let set = new Set(['red', 'green', 'blue']); |
Demo3: forEach方法
1 | let set = new Set([1, 2, 3]); |
Demo4: 遍历的应用
...和set结合,去除数组的重复成员
1 | let arr = [3, 5, 2, 2, 5, 5]; |
- 转换为数组后,
map和filter方法也可以用于Set了
1 | let set = new Set([1, 2, 3]); |
- 集合运算
1 | let a = new Set([1, 2, 3]); |
11.2 WeakSet
说明:Set的弱引用版本
WeakSet的成员只能是对象- 垃圾回收机制不考虑
WeakSet对成员的引用 WeakSet是不可遍历的(因为无法引用WeakSet的成员)
技巧:WeakSet的一个用处,是储存DOM节点,而不用担心这些节点从文档移除时,会引发内存泄漏
11.2.1 构造器
说明:WeakSet是一个构造函数,可以使用new命令,创建WeakSet数据结构
| 参数 | 类型 | 说明 | 必需 |
|---|---|---|---|
| 1 | iterable接口 |
一个数组或类似数组的对象(成员必须是对象) | 否 |
1 | var a = [[1,2], [3,4]]; |
11.2.2 实例方法
| 实例方法 | 说明 |
|---|---|
WeakSet.prototype.add(value) |
向WeakSet实例添加一个新成员 |
WeakSet.prototype.delete(value) |
清除WeakSet实例的指定成员 |
WeakSet.prototype.has(value) |
返回一个布尔值,表示某个值是否在WeakSet实例之中 |
1 | var ws = new WeakSet(); |
11.3 Map
说明:ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键
11.3.1 Map 结构的目的和基本用法
说明:Map结构提供了值—值的对应,是一种更完善的Hash结构实现。如果你需要键值对的数据结构,Map比Object更合适
Map 构造器
| 参数 | 类型 | 说明 | 必需 |
|---|---|---|---|
| 1 | array |
该数组的成员是一个个表示键值对的数组 | 否 |
注意:Map区分不同键的方式类似===
| 键类型 | 判断标准 |
|---|---|
引用类型 |
Map的键跟内存地址绑定的,只要内存地址不一样,就视为两个键 |
number、string、boolean |
只要两个值严格相等,就视为一个键(包括0和-0) |
NaN |
Map将其视为同一个键(虽然NaN不严格相等于自身) |
1 | var map = new Map([ |
11.3.2 实例的属性和操作方法
| 实例属性 | 类型 | 说明 |
|---|---|---|
size |
number |
Map结构的成员总数 |
| 实例方法 | 说明 |
|---|---|
set(key, value) |
如果key已经有值,则键值会被更新,否则就新生成该键。返回整个Map结构,因此可以采用链式写法 |
get(key) |
读取key对应的键值,如果找不到key,返回undefined |
has(key) |
返回一个布尔值,表示某个键是否在Map数据结构中 |
delete(key) |
删除某个键,返回true。如果删除失败,返回false |
clear() |
清除所有成员,没有返回值 |
1 | let map = new Map() |
11.3.3 遍历方法
说明:Map结构本身就可以遍历,默认的遍历器接口为Map.prototype.entries()
注意:Map的遍历顺序就是插入顺序
| 遍历方法 | 说明 |
|---|---|
keys() |
返回键名的遍历器 |
values() |
返回键值的遍历器 |
entries() |
返回所有成员的遍历器 |
forEach() |
遍历Map的所有成员 |
Demo1: 基本使用
1 | let map = new Map([ |
Demo2: Map结构的默认遍历器接口(Symbol.iterator属性),就是entries方法
1 | map[Symbol.iterator] === map.entries |
Demo3: 结合使用扩展运算符,将Map结构转为数组结构,实现Map的遍历和过滤
1 | let map0 = new Map() |
Map.prototype.forEach()
说明:和数组的forEach()方法用法一致(还可以接受第二个参数,用来绑定this)
1 | map.forEach(function(value, key, map) { |
11.3.4 与其他数据结构的互相转换

(1) Map转为数组:使用扩展运算符
1 | let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']); |
(2) 数组转为Map(数组的成员为有两个成员的数组)
1 | new Map([[true, 7], [{foo: 3}, ['abc']]]) |
(3) Map转为对象(前提是所有Map的键都是字符串)
1 | function strMapToObj(strMap) { |
(4) 对象转为Map
1 | function objToStrMap(obj) { |
(5) Map转为JSON:分两种情况
1)转为对象JSON(Map的键名都是字符串):Map -> 对象 -> JSON
1 | function strMapToJson(strMap) { |
2)转为数组JSON(Map的键名有非字符串):Map -> 数组 -> JSON
1 | function mapToArrayJson(map) { |
(6) JSON转为Map
1)JSON->对象->Map(一般情形)
1 | function jsonToStrMap(jsonStr) { |
2)JSON->数组->Map字符串的格式(JSON可以转换为情景2的数组)
1 | function jsonToMap(jsonStr) { |
11.4 WeakMap
设计目的:key是对象的弱引用(垃圾回收机制不将该引用考虑在内),所以其所对应的对象可能会被自动回收。当key被回收后,WeakMap自动移除对应的键值对,从而防止内存泄漏。
用途:WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。
说明:WeakMap与Map在API上的区别
- 没有遍历操作(即没有key()、values()和entries()方法)
- 没有
size属性 - 无法清空(即不支持
clear方法) - 只有四个方法可用:
get()、set()、has()、delete()
Demo1: 基本用法
1 | var wm = new WeakMap(); |
Demo2: DOM节点作为键名
1 | let myElement = document.getElementById('logo'); |
Demo3: 部署私有属性Countdown类的两个内部属性_counter和_action,是实例的弱引用,所以如果删除实例,它们也就随之消失,不会造成内存泄漏
1 | let _counter = new WeakMap(); |